import { Inject } from '@nestjs/common';
import { RedisService } from 'src/module/common/redis/redis.service';
import { paramsKeyFormat } from '../utils/decorator';

/**
 * 清除缓存
 * @param CACHE_NAME - 缓存名称
 * @param CACHE_KEY - 缓存键
 * @returns 
 */
export function CacheEvict(CACHE_NAME: string, CACHE_KEY: string) {
  const injectRedis = Inject(RedisService);
  return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    injectRedis(target, 'redis');
    const originMethod = descriptor.value;
    descriptor.value = async function (...args: any[]) {
      // console.log(args, 'args');
      const key = paramsKeyFormat(originMethod, CACHE_KEY, args);
      // console.log('CacheEvict key:', `${CACHE_NAME}${key}`);
      
      if (key === '*') {
        const res = await this.redis.keys(`${CACHE_NAME}*`);
        if (res.length) {
          await this.redis.del(res);
        }
      } else if (key !== null) {
        await this.redis.del(`${CACHE_NAME}${key}`);
      } else {
        await this.redis.del(`${CACHE_NAME}${CACHE_KEY}`);
      }

      return await originMethod.apply(this, args);
    };
  };
}

/**
 * 缓存数据
 * @param CACHE_NAME - 缓存名称
 * @param CACHE_KEY - 缓存键
 * @param CACHE_EXPIRESIN - 缓存过期时间
 * @returns 
 */
export function Cacheable(CACHE_NAME: string, CACHE_KEY: string, CACHE_EXPIRESIN?: number) {
  const injectRedis = Inject(RedisService);

  return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    injectRedis(target, 'redis');
    const originMethod = descriptor.value;

    descriptor.value = async function (...args: any[]) {
      const key = paramsKeyFormat(originMethod, CACHE_KEY, args);
      // console.log('Cacheable key:', `${CACHE_NAME}${key}`);

      if (key === null) {
        return await originMethod.apply(this, args);
      }

      const cacheResult = await this.redis.get(`${CACHE_NAME}${key}`);

      if (!cacheResult) {
        const result = await originMethod.apply(this, args);
        await this.redis.set(`${CACHE_NAME}${key}`, result, CACHE_EXPIRESIN);
        return result;
      }

      return cacheResult;
    };
  };
}
